#include <core/log.h>
#include <core/file.h>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>

namespace Core
{
    String LogOutput::MessageTypeToString(MessageType type)
    {
        switch(type)
        {
        case LogOutput::Warning:
            return _TEXT("Warning");
        case LogOutput::Error:
            return _TEXT("Error");
        case LogOutput::Notice:
            return _TEXT("Notice");
        case LogOutput::Info:
            return _TEXT("Info");
        }
        return _TEXT("Unknown");
    }

    Log::LogOutputHash Log::hash(const LogOutput* f)
    {
        return reinterpret_cast<LogOutputHash>(f);
    }

    Log& Log::instance()
    {
        static Log log;
        return log;
    }

    void Log::addLogFormat(const LogOutput* f)
    {
        Log::LogOutputHash h = Log::hash(f);
        m_outputs.insert(OUTPUTS_MAP::value_type(h, const_cast<LogOutput*>(f)));
    }

    void Log::removeLogFormat(const LogOutput* f)
    {
        Log::LogOutputHash h = Log::hash(f);
        m_outputs.erase(h);
    }

    void Log::print(LogOutput::MessageType msgType, const std::string& filename,
                    int line, const Core::String& s)
    {
        BOOST_FOREACH(OUTPUTS_MAP::value_type val, m_outputs)
        {
            val.second->print(msgType, filename, line, s);
        }
    }

    void Log::print(LogOutput::MessageType msgType, const Core::String& s)
    {
        BOOST_FOREACH(OUTPUTS_MAP::value_type val, m_outputs)
        {
            val.second->print(msgType, s);
        }
    }
    Log::Log()
    {

    }

    Log::~Log()
    {

    }

    //text log output impl
    TextLogOutput::TextLogOutput(std::ostream& o) : m_outputStream(&o)
    {
    }

    TextLogOutput::~TextLogOutput()
    {
    }

    void TextLogOutput::print(MessageType typeOfMessage, const std::string& filename, int line, const Core::String& s)
    {

    }

    void TextLogOutput::print(MessageType typeOfMessage, const Core::String& s)
    {
        stream() << LogOutput::MessageTypeToString(typeOfMessage).c_str()
                 << s.c_str() << std::endl;
    }

    std::string GetSomeInterface()
    {
        return std::string();
    }

    std::string Interface2::get()
    {
        return std::string();
    }
}